home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_02_03 / 2n03047a < prev    next >
Text File  |  1991-01-14  |  15KB  |  532 lines

  1.  
  2. ;-------------------------------------------------------------------
  3. ; BEZ.ASM -- Logic to quickly compute the points along a bezier curve.
  4. ;
  5. ;      Assembly :  TASM BEZ;
  6. ;
  7. ;      Should be linked with Turbo-C V2.0 small memory model.
  8. ;
  9. ; Author : Bob Zigon
  10. ; Date   : July 23, 1989
  11. ;-------------------------------------------------------------------
  12.  
  13. ;
  14. ; NOTE : This code is assembled with the .287 directive to avoid the 
  15. ;        generation of the unnecessary FWAITS on an AT or '386 class 
  16. ;        machine. If this code is to be executed on an 8087, the
  17. ;       .287 directive must be commented out.
  18. ;
  19.         .287
  20.  
  21.         dosseg
  22.         .model small
  23.  
  24. ;-------------------------------------------------------------------
  25. ;                          EQUATES
  26. ;-------------------------------------------------------------------
  27. MaxControl   equ 10               ; Max number of control points
  28. MaxDivisions equ 151              ; Max number of divisions for t
  29.  
  30. ;-------------------------------------------------------------------
  31. ;                        VARIABLE DECLARATIONS
  32. ;-------------------------------------------------------------------
  33.         .data
  34.         extrn _XvpMin:word,_XvpMax:word,_YvpMin:word,_YvpMax:word
  35.         extrn _XCpMin:qword,_XCpMax:qword,_YCpMin:qword,_YCpMax:qword
  36.         extrn _XCpScr:word,_YCpScr:word,_XCp:qword,_YCp:qword
  37.         extrn _XCurve:qword,_YCurve:qword
  38.  
  39. K1        dq ?                      ; Coefficient for transforming X
  40. Q1        dq ?
  41. K2        dq ?                      ; Coefficient for transforming Y
  42. Q2        dq ?
  43.  
  44. T         dq MaxControl dup (?)
  45. BCoef     dq MaxControl dup (?)     ; Double Prec array of Binomial Coefficients
  46. OneMinusT dq MaxControl dup (?)
  47. NumTerms  dw ?                      ; Number of terms in the summations
  48.  
  49.         .code
  50.         public _Binomial, _BezierToScreen, _WToVConst
  51.         public XformWXtoScr, XformWYtoScr
  52.  
  53. ; -------------------------------------------------------------------
  54. ; Binomial  -- This routine precomputes the table of binomial coefficients
  55. ;              for a given number of control points.
  56. ;
  57. ;    The table of N coefficients is computed according to the
  58. ; following recursive formula :
  59. ;
  60. ;         N       N-1       N-1
  61. ;        C   =  C      +  C
  62. ;         i       i         i-1
  63. ; C Prototype :
  64. ;
  65. ;        void Binomial(short int NumControl)
  66. ;
  67. ; Input    : 4[BP] -- Number of control points > 1
  68. ; Output   : The BCoef array is filled with the coefficients.
  69. ; -------------------------------------------------------------------
  70. NumControl  equ  4[bp]
  71.  
  72. _Binomial proc near
  73.       push bp
  74.       mov bp,sp
  75.       push si
  76.       push di                     ; Save in case Register Variables = ON
  77.  
  78.       mov ax,NumControl
  79.       mov NumTerms,ax
  80. ;
  81. ; Begin by initializing the BCoef array to
  82. ;
  83. ;   1.0   0  0  0 .... 0
  84. ;         <--- N-1 ---->
  85. ;
  86.       fld1
  87.       fstp qword ptr BCoef        ; Store the 1.0
  88.       fwait
  89.       lea di,BCoef+8
  90.       mov cx,ax
  91.       dec cx
  92.       shl cx,1
  93.       shl cx,1
  94.       cld
  95.       xor ax,ax
  96.       push ds
  97.       pop es                      ; Init ES for the STOSW
  98.       rep stosw                   ; Now store lots of Zeros
  99.  
  100.       mov ax,NumTerms
  101.       cmp ax,MaxControl           ; Number of control points > Number allocated?
  102.       jle Bi10
  103.          xor ax,ax
  104.          mov NumTerms,ax
  105.          jmp short Bi80
  106. ;
  107. ; Now begin the recursive generation of the BCoef array in situ.
  108. ;
  109. ; The equivalent C code is :
  110. ;
  111. ;    for (j = 1; j < NumTerms; j++)
  112. ;    {
  113. ;       Last = 0.0
  114. ;       for (k = 0; k<=j; k++)
  115. ;       {
  116. ;          Temp     = BCoef[k]+Last
  117. ;          Last     = BCoef[k]
  118. ;          BCoef[k] = Temp
  119. ;       }
  120. ;    }
  121. ;
  122.  
  123. Bi10: mov ax,1                    ; AX is j
  124. Bi20: cmp ax,NumTerms
  125.       je Bi80
  126.          fldz                     ; Last is on the stack
  127.          xor bx,bx                ; BX is k
  128.          lea di,BCoef
  129. Bi30:    cmp bx,ax
  130.          ja Bi40
  131.             fld qword ptr [di]    ; Load BCoef[k]
  132.             fld st                ; Duplicate top of stack
  133.             fadd st,st(2)         ; Temp = BCoef[k]+Last
  134.             fxch                  ; Temp <-> BCoef[k]
  135.             fstp st(2)            ; Store BCoef[k] to Last and pop
  136.             fstp qword ptr [di]   ; Store Temp out to BCoef[k]
  137.             add di,8              ; Adv to next BCeof
  138.             inc bx
  139.             jmp Bi30
  140. Bi40:    fstp st                  ; Clean up the coprocessor stack
  141.          fwait
  142.          inc ax
  143.       jmp Bi20
  144.  
  145. Bi80: pop di
  146.       pop si
  147.       mov sp,bp                   ; Pop of the local variables
  148.       pop bp                      ; Reset BP
  149.       ret
  150. _Binomial endp
  151.  
  152. ; -------------------------------------------------------------------
  153. ; _BezierToScreen -- Compute the points along the Bezier curve and
  154. ;                    transform them to screen coordinates.
  155. ;
  156. ; C Prototype :
  157. ;
  158. ;    void BezierToScreen(short int, short int, short int *, short int *)
  159. ;
  160. ; Input  :  4[BP] -- Number of divisions of the parameter
  161. ;           6[BP] -- Number of Control Points
  162. ;           8[bp] -- Ptr to X Screen Coordinates
  163. ;          10[bp] -- Ptr to Y Screen Coordinates
  164. ;
  165. ; Output : The array of X and Y screen coordinates.
  166. ; -------------------------------------------------------------------
  167. TDivisions   equ 4[bp]
  168. NP           equ 6[bp]
  169. XV           equ 8[bp]
  170. YV           equ 10[bp]
  171.  
  172. _BezierToScreen proc near
  173.       local u:qword,du:qword
  174.       local XCurvePtr:word,YCurvePtr:word
  175.       local NumCurvePts:word=AutoSize
  176.       push bp
  177.       mov bp,sp
  178.       sub sp,AutoSize             ; Allocate some local variables
  179.       push si
  180.       push di                     ; Save in case Register Variables = ON
  181.  
  182.       mov ax,NP
  183.       lea si,_XCp
  184.       lea di,_XCpScr
  185.       call XformWXtoScr           ; Convert XCp to screen coordinates
  186.  
  187.       mov ax,NP
  188.       lea si,_YCp
  189.       lea di,_YCpScr
  190.       call XformWYtoScr           ; Convert YCp to screen coordinates
  191. ;
  192. ; Now, compute the coordinates of the curve.
  193. ;
  194.       mov ax,word ptr TDivisions
  195.       inc ax
  196.       mov NumCurvePts,ax          ; Number of points on the curve
  197.  
  198.       fld1
  199.       fidiv word ptr TDivisions
  200.       fstp du                     ; du = 1/TDivisions
  201.       fldz
  202.       fstp u                      ; u = 0.0
  203.       fwait
  204.       lea ax,_XCurve
  205.       mov XCurvePtr,ax
  206.       lea ax,_YCurve
  207.       mov YCurvePtr,ax
  208.  
  209. ;
  210. ; Since the address of _XCp and _YCp doesn't change, why push them
  211. ; on the stack every time you need to call Bezier. Push them
  212. ; once here, and clean up on exit.
  213. ;
  214.       lea ax,_YCp
  215.       push ax
  216.       lea ax,_XCp
  217.       push ax
  218.  
  219. BS10: mov ax,NumCurvePts
  220.       or ax,ax                    ; EXIT when no more points to compute
  221.       jz BS20
  222.          mov ax, word ptr u+6
  223.          push ax
  224.          mov ax, word ptr u+4
  225.          push ax
  226.          mov ax, word ptr u+2
  227.          push ax
  228.          mov ax, word ptr u
  229.          push ax
  230.  
  231.          call Bezier              ; Compute X(t) and Y(t)
  232.          add sp,2*4               ; Pop the t parameter
  233.  
  234.          mov si,YCurvePtr
  235.          fstp qword ptr [si]      ; Save and pop Y(t)
  236.          add si,8
  237.          mov YCurvePtr,si
  238.  
  239.          mov si,XCurvePtr
  240.          fstp qword ptr [si]      ; Save and pop X(t)
  241.          add si,8
  242.          mov XCurvePtr,si
  243.  
  244.          fld u
  245.          fadd du
  246.          fstp u                   ; Increment u by du
  247.          fwait
  248.  
  249.          dec NumCurvePts          ; 1 less point to consider
  250.       jmp short BS10
  251.  
  252.  
  253. BS20: add sp,2*2                  ; Pop address of _XCp and _YCp
  254.       mov ax,TDivisions
  255.       inc ax
  256.       lea si,_XCurve
  257.       mov di,XV
  258.       call XformWXtoScr           ; Convert X curve values to screen coordinates
  259.  
  260.       mov ax,TDivisions
  261.       inc ax
  262.       lea si,_YCurve
  263.       mov di,YV
  264.       call XformWYtoScr           ; Convert Y curve values to screen coordinates
  265.  
  266.       pop di
  267.       pop si
  268.       mov sp,bp                   ; Pop of the local variables
  269.       pop bp                      ; Reset BP
  270.       ret
  271. _B